์ต์ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฌ๊ณ ํ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ๋ฅผ ์ํ JavaScript ๋น๋๊ธฐ ์ปจํ ์คํธ ๊ด๋ฆฌ, ๋์ ํ์ง ์ ๋ต, ๊ฒ์ฆ ๊ธฐ๋ฒ์ ๋ํ ์ฌ์ธต ๋ถ์.
JavaScript ๋น๋๊ธฐ ์ปจํ ์คํธ ๋์ ํ์ง: ์ปจํ ์คํธ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ ๊ฒ์ฆ
๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ํ๋ JavaScript ๊ฐ๋ฐ์ ์ด์์ผ๋ก, I/O ์์ ๊ณผ ๋ณต์กํ ์ฌ์ฉ์ ์ํธ์์ฉ์ ํจ์จ์ ์ผ๋ก ์ฒ๋ฆฌํ ์ ์๊ฒ ํด์ค๋๋ค. ํ์ง๋ง ๋น๋๊ธฐ ์์ ์ ๋ณต์ก์ฑ์ ๋ฏธ๋ฌํ์ง๋ง ์ค๋ํ ๋ฌธ์ ์ธ ๋น๋๊ธฐ ์ปจํ ์คํธ ๋์(async context leak)๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค. ์ด๋ฌํ ๋์๋ ๋น๋๊ธฐ ์์ ์ด ์๋๋ ์๋ช ์ ๋์ด ๊ฐ์ฒด๋ ๋ฐ์ดํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ์ฌ ๊ฐ๋น์ง ์ปฌ๋ ํฐ๊ฐ ๋ฉ๋ชจ๋ฆฌ๋ฅผ ํ์ํ์ง ๋ชปํ๊ฒ ํ ๋ ๋ฐ์ํฉ๋๋ค. ์ด ๊ฒ์๋ฌผ์์๋ ๋น๋๊ธฐ ์ปจํ ์คํธ ๋์์ ๋ณธ์ง, ์ ์ฌ์ ์ํฅ, ๊ทธ๋ฆฌ๊ณ ์ปจํ ์คํธ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ์ ํ์ง ๋ฐ ๊ฒ์ฆ์ ์ํ ํจ๊ณผ์ ์ธ ์ ๋ต์ ๋ํด ์์๋ด ๋๋ค.
JavaScript์ ๋น๋๊ธฐ ์ปจํ ์คํธ ์ดํดํ๊ธฐ
JavaScript์์ ๋น๋๊ธฐ ์์ ์ ์ผ๋ฐ์ ์ผ๋ก ์ฝ๋ฐฑ, Promise ๋๋ async/await ๊ตฌ๋ฌธ์ ์ฌ์ฉํ์ฌ ์ฒ๋ฆฌ๋ฉ๋๋ค. ์ด๋ฌํ ๊ฐ ๋ฉ์ปค๋์ฆ์ ๋น๋๊ธฐ ์์ ์ด ์๋ํ๋ ์คํ ํ๊ฒฝ์ธ '์ปจํ ์คํธ'๋ผ๋ ๊ฐ๋ ์ ๋์ ํฉ๋๋ค. ์ด ์ปจํ ์คํธ์๋ ๋ณ์, ํจ์ ํด๋ก์ ๋๋ ํด๋น ์์ ๊ณผ ๊ด๋ จ๋ ๊ธฐํ ๋ฐ์ดํฐ ๊ตฌ์กฐ๊ฐ ํฌํจ๋ ์ ์์ต๋๋ค. ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋๋ฉด ๊ด๋ จ ์ปจํ ์คํธ๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๋ฐฉ์งํ๊ธฐ ์ํด ์ด์์ ์ผ๋ก๋ ํด์ ๋์ด์ผ ํฉ๋๋ค. ํ์ง๋ง ์ด๊ฒ์ด ํญ์ ๋ณด์ฅ๋๋ ๊ฒ์ ์๋๋๋ค.
๋ค์์ ๊ฐ๋จํ ์์ ๋ฅผ ์ดํด๋ณด๊ฒ ์ต๋๋ค:
async function processData(data) {
const largeObject = new Array(1000000).fill(0); // ํฐ ๊ฐ์ฒด ์๋ฎฌ๋ ์ด์
await new Promise(resolve => setTimeout(resolve, 100)); // ๋น๋๊ธฐ ์์
์๋ฎฌ๋ ์ด์
// ํ์์์ ์ดํ largeObject๋ ๋ ์ด์ ํ์ํ์ง ์์
return data.length;
}
async function main() {
const data = "Some input data";
const result = await processData(data);
console.log(`Result: ${result}`);
}
main();
์ด ์์ ์์ `largeObject`๋ `processData` ํจ์ ๋ด์์ ์์ฑ๋ฉ๋๋ค. ์ด์์ ์ผ๋ก๋ Promise๊ฐ ํด๊ฒฐ๋๊ณ `processData`๊ฐ ์๋ฃ๋๋ฉด `largeObject`๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋์์ด ๋์ด์ผ ํฉ๋๋ค. ํ์ง๋ง Promise์ ๋ด๋ถ ๊ตฌํ์ด๋ ์ฃผ๋ณ ์ปจํ ์คํธ์ ์ผ๋ถ๊ฐ ์ค์๋ก `largeObject`์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๋ก ์ด์ด์ง ์ ์์ต๋๋ค. ์ด๋ ํนํ ์ค๋ ์คํ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ ๋น๋ฒํ ๋น๋๊ธฐ ์์ ์ ์ฒ๋ฆฌํ ๋ ๋ฌธ์ ๊ฐ ๋ฉ๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์์ ์ํฅ
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์๋ ์ ํ๋ฆฌ์ผ์ด์ ์ฑ๋ฅ๊ณผ ์์ ์ฑ์ ์ฌ๊ฐํ ์ํฅ์ ๋ฏธ์น ์ ์์ต๋๋ค:
- ๋ฉ๋ชจ๋ฆฌ ์๋น ์ฆ๊ฐ: ๋์๋ ์ปจํ ์คํธ๋ ์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ถ์ ๋์ด ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ์ ์ฐจ ์ฆ๊ฐ์ํต๋๋ค. ์ด๋ ์ฑ๋ฅ ์ ํ๋ก ์ด์ด์ง๊ณ ๊ฒฐ๊ตญ ๋ฉ๋ชจ๋ฆฌ ๋ถ์กฑ ์ค๋ฅ๋ฅผ ์ ๋ฐํ ์ ์์ต๋๋ค.
- ์ฑ๋ฅ ์ ํ: ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ์ฆ๊ฐํจ์ ๋ฐ๋ผ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ฃผ๊ธฐ๊ฐ ๋ ๋น๋ฒํด์ง๊ณ ์๊ฐ์ด ์ค๋ ๊ฑธ๋ฆฌ๊ฒ ๋์ด ๊ท์คํ CPU ๋ฆฌ์์ค๋ฅผ ์๋ชจํ๊ณ ์ ํ๋ฆฌ์ผ์ด์ ์๋ต์ฑ์ ์ํฅ์ ๋ฏธ์นฉ๋๋ค.
- ์ ํ๋ฆฌ์ผ์ด์ ๋ถ์์ ์ฑ: ๊ทน๋จ์ ์ธ ๊ฒฝ์ฐ ๋ฉ๋ชจ๋ฆฌ ๋์๋ก ์ธํด ์ฌ์ฉ ๊ฐ๋ฅํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ณ ๊ฐ๋์ด ์ ํ๋ฆฌ์ผ์ด์ ์ด ์ถฉ๋ํ๊ฑฐ๋ ์๋ตํ์ง ์๊ฒ ๋ ์ ์์ต๋๋ค.
- ์ด๋ ค์ด ๋๋ฒ๊น : ๋น๋๊ธฐ ์ปจํ ์คํธ ๋์๋ ๊ทผ๋ณธ ์์ธ์ด ๋น๋๊ธฐ ์์ ์ด๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๊น์์ด ์จ์ด ์์ ์ ์์ด ๋๋ฒ๊น ํ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์ ํ์งํ๊ธฐ
JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋น๋๊ธฐ ์ปจํ ์คํธ ๋์๋ฅผ ํ์งํ๋ ๋ฐ๋ ์ฌ๋ฌ ๊ธฐ๋ฒ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
1. ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง ๋๊ตฌ
๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง ๋๊ตฌ๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์๋ณํ๋ ๋ฐ ํ์์ ์ ๋๋ค. Node.js์ ์น ๋ธ๋ผ์ฐ์ ๋ชจ๋ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๋ถ์ํ๊ณ , ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์๋ณํ๋ฉฐ, ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ถ์ ํ ์ ์๋ ๋ด์ฅ ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ฌ๋ฅผ ์ ๊ณตํฉ๋๋ค.
- Chrome ๊ฐ๋ฐ์ ๋๊ตฌ: Chrome ๊ฐ๋ฐ์ ๋๊ตฌ๋ ํ ์ค๋ ์ท์ ์ฐ๊ณ , ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ฅธ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ๊ธฐ๋กํ๋ฉฐ, ๋ถ๋ฆฌ๋ DOM ํธ๋ฆฌ(๋ธ๋ผ์ฐ์ ํ๊ฒฝ์์ ํํ ๋ฉ๋ชจ๋ฆฌ ๋์ ์์ธ)๋ฅผ ์๋ณํ ์ ์๋ ๊ฐ๋ ฅํ ๋ฉ๋ชจ๋ฆฌ ํจ๋์ ์ ๊ณตํฉ๋๋ค. 'ํ์๋ผ์ธ์์ ํ ๋น ๊ณ์ธก' ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ํน์ ๋น๋๊ธฐ ์์ ๊ณผ ๊ด๋ จ๋ ๋ฉ๋ชจ๋ฆฌ ํ ๋น์ ์ถ์ ํ ์ ์์ต๋๋ค.
- Node.js Inspector: Node.js Inspector๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ฒ๊ฑฐ(์: Chrome ๊ฐ๋ฐ์ ๋๊ตฌ)๋ฅผ Node.js ํ๋ก์ธ์ค์ ์ฐ๊ฒฐํ๊ณ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๊ฒ์ฌํ ์ ์์ต๋๋ค. `heapdump` ๋ชจ๋์ ์ฌ์ฉํ์ฌ ํ ์ค๋ ์ท์ ์์ฑํ๊ณ Chrome ๊ฐ๋ฐ์ ๋๊ตฌ๋ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๋ถ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ถ์ํ ์ ์์ต๋๋ค. `clinic.js`์ ๊ฐ์ ๋๊ตฌ๋ ๋งค์ฐ ์ ์ฉํฉ๋๋ค.
Chrome ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ์์ :
- Chrome์์ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฝ๋๋ค.
- Chrome ๊ฐ๋ฐ์ ๋๊ตฌ๋ฅผ ์ฝ๋๋ค (Ctrl+Shift+I ๋๋ Cmd+Option+I).
- ๋ฉ๋ชจ๋ฆฌ ํจ๋๋ก ์ด๋ํฉ๋๋ค.
- 'ํ์๋ผ์ธ์์ ํ ๋น ๊ณ์ธก'์ ์ ํํฉ๋๋ค.
- ๊ธฐ๋ก์ ์์ํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ ๋ฐํ๋ค๊ณ ์์ฌ๋๋ ์์ ์ ์ํํฉ๋๋ค.
- ๊ธฐ๋ก์ ์ค์งํฉ๋๋ค.
- ๋ฉ๋ชจ๋ฆฌ ํ ๋น ํ์๋ผ์ธ์ ๋ถ์ํ์ฌ ์์๋๋ก ๊ฐ๋น์ง ์ปฌ๋ ์ ๋์ง ์๋ ๊ฐ์ฒด๋ฅผ ์๋ณํฉ๋๋ค.
2. ํ ์ค๋ ์ท
ํ ์ค๋ ์ท์ ํน์ ์์ ์ JavaScript ํ ์ํ๋ฅผ ์บก์ฒํฉ๋๋ค. ์๋ก ๋ค๋ฅธ ์๊ฐ์ ์ฐ์ ํ ์ค๋ ์ท์ ๋น๊ตํจ์ผ๋ก์จ ์์๋ณด๋ค ์ค๋ซ๋์ ๋ฉ๋ชจ๋ฆฌ์ ์ ์ง๋๋ ๊ฐ์ฒด๋ฅผ ์๋ณํ ์ ์์ต๋๋ค. ์ด๋ ์ ์ฌ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ฐพ์๋ด๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค.
Node.js์ heapdump๋ฅผ ์ฌ์ฉํ ์์ :
const heapdump = require('heapdump');
async function processData(data) {
const largeObject = new Array(1000000).fill(0);
await new Promise(resolve => setTimeout(resolve, 100));
return data.length;
}
async function main() {
const data = "Some input data";
const result = await processData(data);
console.log(`Result: ${result}`);
heapdump.writeSnapshot('heapdump1.heapsnapshot');
await new Promise(resolve => setTimeout(resolve, 1000)); // GC๊ฐ ์คํ๋๋๋ก ์ ์ ๋๊ธฐ
heapdump.writeSnapshot('heapdump2.heapsnapshot');
}
main();
์ด ์ฝ๋๋ฅผ ์คํํ ํ Chrome ๊ฐ๋ฐ์ ๋๊ตฌ๋ ๋ค๋ฅธ ๋ฉ๋ชจ๋ฆฌ ๋ถ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ `heapdump1.heapsnapshot` ๋ฐ `heapdump2.heapsnapshot` ํ์ผ์ ๋ถ์ํ์ฌ ๋น๋๊ธฐ ์์ ์ ํ์ ํ ์ํ๋ฅผ ๋น๊ตํ ์ ์์ต๋๋ค.
3. WeakRef์ FinalizationRegistry
์ต์ JavaScript๋ ๊ฐ์ฒด ์๋ช ์ฃผ๊ธฐ๋ฅผ ์ถ์ ํ๊ณ ๊ฐ์ฒด๊ฐ ์ธ์ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋์ง ๊ฐ์งํ๋ ๋ฐ ์ ์ฉํ ๋๊ตฌ์ธ `WeakRef`์ `FinalizationRegistry`๋ฅผ ์ ๊ณตํฉ๋๋ค. `WeakRef`๋ ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋ ๊ฒ์ ๋ง์ง ์์ผ๋ฉด์ ํด๋น ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ ์ ์๊ฒ ํด์ค๋๋ค. `FinalizationRegistry`๋ ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋ ๋ ์คํ๋ ์ฝ๋ฐฑ์ ๋ฑ๋กํ ์ ์๊ฒ ํด์ค๋๋ค.
WeakRef์ FinalizationRegistry๋ฅผ ์ฌ์ฉํ ์์ :
const registry = new FinalizationRegistry(heldValue => {
console.log(`๊ฐ ${heldValue}๋ฅผ ๊ฐ์ง ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์
๋์์ต๋๋ค.`);
});
async function processData(data) {
const largeObject = new Array(1000000).fill(0);
const weakRef = new WeakRef(largeObject);
registry.register(largeObject, "largeObject");
await new Promise(resolve => setTimeout(resolve, 100));
return data.length;
}
async function main() {
const data = "Some input data";
const result = await processData(data);
console.log(`Result: ${result}`);
// ๋ช
์์ ์ผ๋ก GC ํธ๋ฆฌ๊ฑฐ ์๋ (๋ณด์ฅ๋์ง ์์)
global.gc();
await new Promise(resolve => setTimeout(resolve, 1000)); // GC์ ์๊ฐ ์ ๊ณต
}
main();
์ด ์์ ์์๋ `largeObject`์ ๋ํ `WeakRef`๋ฅผ ์์ฑํ๊ณ `FinalizationRegistry`์ ๋ฑ๋กํฉ๋๋ค. `largeObject`๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋ฉด `FinalizationRegistry`์ ์ฝ๋ฐฑ์ด ์คํ๋์ด ๊ฐ์ฒด๊ฐ ์ ๋ฆฌ๋์์์ ํ์ธํ ์ ์์ต๋๋ค. `global.gc()`๋ฅผ ๋ช ์์ ์ผ๋ก ํธ์ถํ๋ ๊ฒ์ ๊ฐ๋น์ง ์ปฌ๋ ํฐ์ ์ ์์ ์ธ ์๋์ ๋ฐฉํดํ ์ ์์ผ๋ฏ๋ก ํ๋ก๋์ ์ฝ๋์์๋ ์ผ๋ฐ์ ์ผ๋ก ๊ถ์ฅ๋์ง ์์ต๋๋ค. ์ด๋ ํ ์คํธ ๋ชฉ์ ์ผ๋ก ์ฌ์ฉ๋ฉ๋๋ค.
4. ์๋ํ๋ ํ ์คํธ ๋ฐ ๋ชจ๋ํฐ๋ง
์๋ํ๋ ํ ์คํธ ๋ฐ ๋ชจ๋ํฐ๋ง ์ธํ๋ผ์ ๋ฉ๋ชจ๋ฆฌ ๋์ ํ์ง๋ฅผ ํตํฉํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ํ๋ก๋์ ํ๊ฒฝ์ ๋๋ฌํ๋ ๊ฒ์ ๋ฐฉ์งํ๋ ๋ฐ ๋์์ด ๋ ์ ์์ต๋๋ค. Mocha, Jest ๋๋ Cypress์ ๊ฐ์ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๊ตฌ์ฒด์ ์ผ๋ก ํ์ธํ๋ ํ ์คํธ๋ฅผ ๋ง๋ค ์ ์์ต๋๋ค. ์ด๋ฌํ ํ ์คํธ๋ CI/CD ํ์ดํ๋ผ์ธ์ ์ผ๋ถ๋ก ์คํํ์ฌ ์๋ก์ด ์ฝ๋ ๋ณ๊ฒฝ์ด ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ ๋ฐํ์ง ์๋์ง ํ์ธํ ์ ์์ต๋๋ค.
Jest์ heapdump๋ฅผ ์ฌ์ฉํ ์์ :
const heapdump = require('heapdump');
async function processData(data) {
const largeObject = new Array(1000000).fill(0);
await new Promise(resolve => setTimeout(resolve, 100));
return data.length;
}
describe('Memory Leak Test', () => {
it('๋ฐ์ดํฐ ์ฒ๋ฆฌ ํ ๋ฉ๋ชจ๋ฆฌ๊ฐ ๋์๋์ง ์์์ผ ํฉ๋๋ค', async () => {
const data = "Some input data";
heapdump.writeSnapshot('heapdump_before.heapsnapshot');
const result = await processData(data);
heapdump.writeSnapshot('heapdump_after.heapsnapshot');
// ํ ์ค๋
์ท์ ๋น๊ตํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฐ์ง
// (์ผ๋ฐ์ ์ผ๋ก ๋ฉ๋ชจ๋ฆฌ ๋ถ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ์ฌ ์ค๋
์ท์ ํ๋ก๊ทธ๋๋ฐ ๋ฐฉ์์ผ๋ก ๋ถ์ํด์ผ ํจ)
expect(result).toBeDefined(); // ์์ ๋จ์ธ๋ฌธ
// TODO: ์ฌ๊ธฐ์ ์ค์ ์ค๋
์ท ๋น๊ต ๋ก์ง ์ถ๊ฐ
}, 10000); // ๋น๋๊ธฐ ์์
์ ์ํ ํ์์์ ์ฆ๊ฐ
});
์ด ์์ ๋ `processData` ํจ์๊ฐ ์คํ๋๊ธฐ ์ ๊ณผ ํ์ ํ ์ค๋ ์ท์ ์ฐ๋ Jest ํ ์คํธ๋ฅผ ๋ง๋ญ๋๋ค. ๊ทธ๋ฐ ๋ค์ ํ ์คํธ๋ ํ ์ค๋ ์ท์ ๋น๊ตํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ๊ฐ์งํฉ๋๋ค. ์ฐธ๊ณ : ์์ ํ ์๋ํ๋ ์ค๋ ์ท ๋น๊ต๋ฅผ ๊ตฌํํ๋ ค๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋ถ์์ ์ํด ์ค๊ณ๋ ๋ ์ ๊ตํ ๋๊ตฌ์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ํ์ํฉ๋๋ค. ์ด ์์ ๋ ๊ธฐ๋ณธ ํ๋ ์์ํฌ๋ฅผ ๋ณด์ฌ์ค๋๋ค.
์ปจํ ์คํธ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ ๊ฒ์ฆ
๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ํ์งํ๋ ๊ฒ์ ์ฒซ ๋ฒ์งธ ๋จ๊ณ์ผ ๋ฟ์ ๋๋ค. ์ ์ฌ์ ์ธ ๋์๊ฐ ํ์ธ๋๋ฉด ์ปจํ ์คํธ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ ๋ฆฌ๋๊ณ ์๋์ง ๊ฒ์ฆํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ์ฌ๊ธฐ์๋ ๋์์ ๊ทผ๋ณธ ์์ธ์ ์ดํดํ๊ณ ์ ์ ํ ์์ ์ฌํญ์ ๊ตฌํํ๋ ๊ฒ์ด ํฌํจ๋ฉ๋๋ค.
1. ๊ทผ๋ณธ ์์ธ ์๋ณ
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์์ ๊ทผ๋ณธ ์์ธ์ ํน์ ์ฝ๋์ ์ฌ์ฉ๋ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ํจํด์ ๋ฐ๋ผ ๋ค๋ฅผ ์ ์์ต๋๋ค. ์ผ๋ฐ์ ์ธ ์์ธ์ ๋ค์๊ณผ ๊ฐ์ต๋๋ค:
- ํด์ ๋์ง ์์ ์ฐธ์กฐ: ๋น๋๊ธฐ ์์ ์ด ๋ ์ด์ ํ์ํ์ง ์์ ๊ฐ์ฒด๋ ๋ฐ์ดํฐ์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ค์๋ก ์ ์งํ์ฌ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋ ๊ฒ์ ๋ง์ ์ ์์ต๋๋ค. ์ด๋ ํด๋ก์ , ์ด๋ฒคํธ ๋ฆฌ์ค๋ ๋๋ ๊ฐ๋ ฅํ ์ฐธ์กฐ๋ฅผ ์์ฑํ๋ ๋ค๋ฅธ ๋ฉ์ปค๋์ฆ์ผ๋ก ์ธํด ๋ฐ์ํ ์ ์์ต๋๋ค. ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ํ ํด๋ก์ ์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ์ ๋๋ก ์ ๋ฆฌ๋๋์ง ์ฃผ์ ๊น๊ฒ ๊ฒ์ฌํ์ญ์์ค.
- ์ํ ์ข ์์ฑ: ๊ฐ์ฒด ๊ฐ์ ์ํ ์ข ์์ฑ์ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋ฐฉํดํ ์ ์์ต๋๋ค. ๋ ๊ฐ์ฒด๊ฐ ์๋ก์ ๋ํ ์ฐธ์กฐ๋ฅผ ๊ฐ์ง๊ณ ์์ผ๋ฉด ๋ ์ฐธ์กฐ๊ฐ ๋ชจ๋ ๋์ด์ง ๋๊น์ง ์ด๋ค ๊ฐ์ฒด๋ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋ ์ ์์ต๋๋ค. ๊ฐ๋ฅํ๋ฉด ์ํ ์ข ์์ฑ์ ๋์ผ์ญ์์ค.
- ์ ์ญ ๋ณ์: ์ ์ญ ๋ณ์์ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํ๋ฉด ์๋์น ์๊ฒ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋ฐฉํดํ ์ ์์ต๋๋ค. ๊ฐ๋ฅํ๋ฉด ์ ์ญ ๋ณ์ ์ฌ์ฉ์ ํผํ๊ณ ๋์ ์ง์ญ ๋ณ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ญ์์ค.
- ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ: ๋ฉ๋ชจ๋ฆฌ ๋์๋ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ฒ๊ทธ๋ก ์ธํด ๋ฐ์ํ ์๋ ์์ต๋๋ค. ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๊ฐ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์ผ์ผํค๋ ๊ฒ์ผ๋ก ์์ฌ๋๋ฉด ๋ฌธ์ ๋ฅผ ๊ฒฉ๋ฆฌํ์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ ์ง ๊ด๋ฆฌ์์๊ฒ ๋ณด๊ณ ํ์ญ์์ค.
- ์ํ ์ด๋ฒคํธ ๋ฆฌ์ค๋: DOM ์์๋ ๋ค๋ฅธ ๊ฐ์ฒด์ ์ฐ๊ฒฐ๋ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ ๋ ์ด์ ํ์ํ์ง ์์ ๋ ์ ๊ฑฐํด์ผ ํฉ๋๋ค. ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ์ ๊ฑฐํ๋ ๊ฒ์ ์์ผ๋ฉด ๊ด๋ จ ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋ ๊ฒ์ ๋ง์ ์ ์์ต๋๋ค. ์ปดํฌ๋ํธ๋ ๊ฐ์ฒด๊ฐ ํ๊ดด๋๊ฑฐ๋ ๋ ์ด์ ์ด๋ฒคํธ ์๋ฆผ์ด ํ์ํ์ง ์์ ๋๋ ํญ์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ฅผ ๋ฑ๋ก ํด์ ํ์ญ์์ค.
2. ์ ๋ฆฌ ์ ๋ต ๊ตฌํ
๋ฉ๋ชจ๋ฆฌ ๋์์ ๊ทผ๋ณธ ์์ธ์ด ํ์ธ๋๋ฉด ์ปจํ ์คํธ ๋ฉ๋ชจ๋ฆฌ๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ํด์ ๋๋๋ก ์ ์ ํ ์ ๋ฆฌ ์ ๋ต์ ๊ตฌํํ ์ ์์ต๋๋ค.
- ์ฐธ์กฐ ๋๊ธฐ: ๋ ์ด์ ํ์ํ์ง ์์ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ๋๊ธฐ ์ํด ๋ณ์ ๋ฐ ๊ฐ์ฒด ์์ฑ์ ๋ช ์์ ์ผ๋ก `null` ๋๋ `undefined`๋ก ์ค์ ํ์ญ์์ค.
- ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ๊ฑฐ: `removeEventListener`๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฒคํธ ๋ฆฌ์ค๋๊ฐ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ๋ ๊ฒ์ ๋ฐฉ์งํ์ญ์์ค.
- WeakRef ์ฌ์ฉ: `WeakRef`๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋๋ ๊ฒ์ ๋ง์ง ์์ผ๋ฉด์ ํด๋น ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ์ญ์์ค.
- ํด๋ก์ ์ ์คํ๊ฒ ๊ด๋ฆฌํ๊ธฐ: ํด๋ก์ ์ ํด๋ก์ ๊ฐ ์บก์ฒํ๋ ๋ณ์์ ์ ์ํ์ญ์์ค. ํด๋ก์ ๊ฐ ๋ ์ด์ ํ์ํ์ง ์์ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ์ง ์๋๋ก ํ์ญ์์ค. ํจ์ ํฉํ ๋ฆฌ๋ ์ปค๋ง๊ณผ ๊ฐ์ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ํด๋ก์ ๋ด ๋ณ์์ ๋ฒ์๋ฅผ ์ ์ดํ๋ ๊ฒ์ ๊ณ ๋ คํ์ญ์์ค.
- ๋ฆฌ์์ค ๊ด๋ฆฌ: ํ์ผ ํธ๋ค, ๋คํธ์ํฌ ์ฐ๊ฒฐ, ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฐ๊ฒฐ๊ณผ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ์ ์ ํ๊ฒ ๊ด๋ฆฌํ์ญ์์ค. ์ด๋ฌํ ๋ฆฌ์์ค๊ฐ ๋ ์ด์ ํ์ํ์ง ์์ ๋ ๋ซํ๊ฑฐ๋ ํด์ ๋์๋์ง ํ์ธํ์ญ์์ค.
3. ๊ฒ์ฆ ๊ธฐ๋ฒ
์ ๋ฆฌ ์ ๋ต์ ๊ตฌํํ ํ์๋ ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ํด๊ฒฐ๋์๋์ง ํ์ธํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค. ๋ค์ ๊ธฐ๋ฒ์ ๊ฒ์ฆ์ ์ฌ์ฉํ ์ ์์ต๋๋ค:
- ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง ๋ฐ๋ณต: ์์ ์ค๋ช ํ ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง ๋จ๊ณ๋ฅผ ๋ฐ๋ณตํ์ฌ ์๊ฐ ๊ฒฝ๊ณผ์ ๋ฐ๋ผ ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ด ๋ ์ด์ ์ฆ๊ฐํ์ง ์๋์ง ํ์ธํ์ญ์์ค.
- ํ ์ค๋ ์ท ๋น๊ต: ์ ๋ฆฌ ์ ๋ต์ด ๊ตฌํ๋๊ธฐ ์ ๊ณผ ํ์ ์ฐ์ ํ ์ค๋ ์ท์ ๋น๊ตํ์ฌ ๋์๋ ๊ฐ์ฒด๊ฐ ๋ ์ด์ ๋ฉ๋ชจ๋ฆฌ์ ์๋์ง ํ์ธํ์ญ์์ค.
- ์๋ํ๋ ํ ์คํธ: ์๋ํ๋ ํ ์คํธ๋ฅผ ์ ๋ฐ์ดํธํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฒ์ฌ๋ฅผ ํฌํจ์ํค์ญ์์ค. ํ ์คํธ๋ฅผ ๋ฐ๋ณต์ ์ผ๋ก ์คํํ์ฌ ์ ๋ฆฌ ์ ๋ต์ด ํจ๊ณผ์ ์ด๊ณ ์๋ก์ด ๋ฌธ์ ๋ฅผ ์ผ์ผํค์ง ์๋์ง ํ์ธํ์ญ์์ค. ํ ์คํธ ์คํ ์ค ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋์ ๋ชจ๋ํฐ๋งํ๊ณ ์ ์ฌ์ ์ธ ๋์๋ฅผ ํ์ํ ์ ์๋ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ์ญ์์ค.
- ์ฅ๊ธฐ ์คํ ํ ์คํธ: ์ค์ ์ฌ์ฉ ํจํด์ ์๋ฎฌ๋ ์ด์ ํ๋ ์ฅ๊ธฐ ์คํ ํ ์คํธ๋ฅผ ์คํํ์ฌ ๋จ๊ธฐ ํ ์คํธ ์ค์๋ ๋ช ํํ๊ฒ ๋๋ฌ๋์ง ์์ ์ ์๋ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์๋ณํ์ญ์์ค. ์ด๋ ์ฅ์๊ฐ ์คํ๋ ๊ฒ์ผ๋ก ์์๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ํนํ ์ค์ํฉ๋๋ค.
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์ ๋ฐฉ์ง๋ฅผ ์ํ ๋ชจ๋ฒ ์ฌ๋ก
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์๋ฅผ ๋ฐฉ์งํ๋ ค๋ฉด ์ ์ ์ ์ธ ์ ๊ทผ ๋ฐฉ์๊ณผ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ ์์น์ ๋ํ ๊น์ ์ดํด๊ฐ ํ์ํฉ๋๋ค. ๋ค์์ ๋ฐ๋ผ์ผ ํ ๋ช ๊ฐ์ง ๋ชจ๋ฒ ์ฌ๋ก์ ๋๋ค:
- ์ต์ JavaScript ๊ธฐ๋ฅ ์ฌ์ฉ: `WeakRef`, `FinalizationRegistry` ๋ฐ async/await์ ๊ฐ์ ์ต์ JavaScript ๊ธฐ๋ฅ์ ํ์ฉํ์ฌ ๋น๋๊ธฐ ํ๋ก๊ทธ๋๋ฐ์ ๋จ์ํํ๊ณ ๋ฉ๋ชจ๋ฆฌ ๋์ ์ํ์ ์ค์ด์ญ์์ค.
- ์ ์ญ ๋ณ์ ํผํ๊ธฐ: ์ ์ญ ๋ณ์ ์ฌ์ฉ์ ์ต์ํํ๊ณ ๋์ ์ง์ญ ๋ณ์๋ ๋ฐ์ดํฐ ๊ตฌ์กฐ๋ฅผ ์ฌ์ฉํ์ญ์์ค.
- ์ด๋ฒคํธ ๋ฆฌ์ค๋ ์ ์คํ๊ฒ ๊ด๋ฆฌํ๊ธฐ: ๋ ์ด์ ํ์ํ์ง ์์ ์ด๋ฒคํธ ๋ฆฌ์ค๋๋ ํญ์ ์ ๊ฑฐํ์ญ์์ค.
- ํด๋ก์ ์ ์ ์ํ๊ธฐ: ํด๋ก์ ๊ฐ ์บก์ฒํ๋ ๋ณ์์ ์ ์ํ๊ณ ๋ ์ด์ ํ์ํ์ง ์์ ๊ฐ์ฒด์ ๋ํ ์ฐธ์กฐ๋ฅผ ์ ์งํ์ง ์๋๋ก ํ์ญ์์ค.
- ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง ๋๊ตฌ ์ ๊ธฐ์ ์ผ๋ก ์ฌ์ฉํ๊ธฐ: ๊ฐ๋ฐ ์ํฌํ๋ก์ฐ์ ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง์ ํตํฉํ์ฌ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์กฐ๊ธฐ์ ์๋ณํ๊ณ ํด๊ฒฐํ์ญ์์ค.
- ๋ฉ๋ชจ๋ฆฌ ๋์ ๊ฒ์ฌ๋ฅผ ํฌํจํ ๋จ์ ํ ์คํธ ์์ฑ: ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ์๋์ง ํ์ธํ๊ธฐ ์ํด ๋จ์ ํ ์คํธ๋ฅผ ํตํฉํ์ญ์์ค.
- ์ฝ๋ ๋ฆฌ๋ทฐ: ๊ฐ๋ฐ ํ๋ก์ธ์ค์ ์ฝ๋ ๋ฆฌ๋ทฐ๋ฅผ ํตํฉํ์ฌ ์ ์ฌ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ๋์๋ฅผ ์กฐ๊ธฐ์ ์๋ณํ์ญ์์ค.
- ์ต์ ์ํ ์ ์ง: JavaScript ๋ฐํ์ ํ๊ฒฝ(Node.js ๋๋ ๋ธ๋ผ์ฐ์ )๊ณผ ์๋ํํฐ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ต์ ์ํ๋ก ์ ์งํ์ฌ ๋ฒ๊ทธ ์์ ๋ฐ ์ฑ๋ฅ ๊ฐ์ ์ ์ด์ ์ ๋๋ฆฌ์ญ์์ค.
๊ฒฐ๋ก
๋น๋๊ธฐ ์ปจํ ์คํธ ๋์๋ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฏธ๋ฌํ์ง๋ง ์ ์ฌ์ ์ผ๋ก ํด๋ก์ด ๋ฌธ์ ์ ๋๋ค. ๊ฐ๋ฐ์๋ ๋น๋๊ธฐ ์ปจํ ์คํธ์ ๋ณธ์ง์ ์ดํดํ๊ณ , ํจ๊ณผ์ ์ธ ํ์ง ๊ธฐ๋ฒ์ ์ฌ์ฉํ๋ฉฐ, ์ ๋ฆฌ ์ ๋ต์ ๊ตฌํํ๊ณ , ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๋ฐ๋ฆ์ผ๋ก์จ ์๊ฐ์ด ์ง๋๋ ์ฑ๋ฅ์ด ์ข๊ณ ์์ ์ ์ผ๋ก ์ ์ง๋๋ ๊ฒฌ๊ณ ํ๊ณ ๋ฉ๋ชจ๋ฆฌ ํจ์จ์ ์ธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค. ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ๋ฅผ ์ฐ์ ์ํ๊ณ ๊ฐ๋ฐ ํ๋ก์ธ์ค์ ์ ๊ธฐ์ ์ธ ๋ฉ๋ชจ๋ฆฌ ํ๋กํ์ผ๋ง์ ํตํฉํ๋ ๊ฒ์ JavaScript ์ ํ๋ฆฌ์ผ์ด์ ์ ์ฅ๊ธฐ์ ์ธ ๊ฑด์ ์ฑ๊ณผ ์ ๋ขฐ์ฑ์ ๋ณด์ฅํ๋ ๋ฐ ๋งค์ฐ ์ค์ํฉ๋๋ค.